package GUI.lecturerGUI;

import java.awt.Component;
import java.awt.SystemColor;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.sql.Time;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import GUI.MainGUI;

import common.Perror;

import controllers.LecturerController;
import entities.ComputerizedExam;
import entities.ExtractedExam;
import entities.Question;
import entities.QuestionPerExam;

public class LecturerCheckGrade extends JPanel implements ActionListener,
		ListSelectionListener, KeyListener {

	private static final long serialVersionUID = 1L;
	private LecturerController lecturerCtrl;
	private JTextField txtGrade;
	private TextArea txtComnt;
	private JButton btnMainMenu;
	private JButton btnExit;
	private JLabel lblExam;
	private JLabel lblCmnt;
	private JButton btnApprove;
	private JComboBox cboxExmsCodes;
	private JList lstExams;
	private DefaultListModel model;
	private TextArea txtTxmPreview;
	private ArrayList<ExtractedExam> examCodesLst;
	private ArrayList<ComputerizedExam> examsLst;
	private ArrayList<QuestionPerExam> questionsLst;

	/**
	 * the Lecturer Check the Grade that waiting to approve
	 * 
	 * @param lecturerCtrl
	 *            the lecturer controller
	 */
	public LecturerCheckGrade(LecturerController lecturerCtrl) {

		super();
		this.lecturerCtrl = lecturerCtrl;
		initialize();

	}

	/**
	 * initializing the GUI
	 */
	private void initialize() {
		setBorder(new TitledBorder(null, "Lecturer Grade Approve  : ",
				TitledBorder.LEADING, TitledBorder.TOP, null, null));
		setBackground(SystemColor.activeCaption);
		setBounds(0, 0, MainGUI.setX, MainGUI.setY);
		setLayout(null);
		add(GETtxtComnt());
		add(GETlstExams());
		add(GETtxtTxmPreview());
		add(GETcboxExmCodes());
		add(GETbtnExit());
		add(GETbtnApprove());
		add(GETlblCmnt());
		add(GETtxtGrade());
		add(GETlblExam());
		add(GETbtnMainMenu());
	}
 
	private JList GETlstExams() {
		if (lstExams == null) {
			lstExams = new JList();
			model = new DefaultListModel();
			lstExams.setModel(model);
			lstExams.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			lstExams.setBounds(10, 58, 115, 198);
		}
		return lstExams;
	}

	private TextArea GETtxtComnt() {
		if (txtComnt == null) {
			txtComnt = new TextArea();
			txtComnt.setBounds(10, 315, 480, 145);
			txtComnt.setEnabled(false);
			txtComnt.setText("");
		}
		return txtComnt;
	}

	private TextArea GETtxtTxmPreview() {
		if (txtTxmPreview == null) {
			txtTxmPreview = new TextArea();
			txtTxmPreview.setEditable(false);
			txtTxmPreview.setBounds(131, 58, 359, 198);
		}
		return txtTxmPreview;
	}

	private JComboBox GETcboxExmCodes() {
		if (cboxExmsCodes == null) {
			cboxExmsCodes = new JComboBox();
			cboxExmsCodes.setBounds(10, 28, 480, 20);
		}
		return cboxExmsCodes;
	}

	private JButton GETbtnExit() {
		if (btnExit == null) {
			btnExit = new JButton("EXIT");
			btnExit.setBounds(401, 466, 89, 23);
			btnExit.addActionListener(this);
		}
		return btnExit;
	}

	private JButton GETbtnApprove() {
		if (btnApprove == null) {
			btnApprove = new JButton("Approve");
			btnApprove.setEnabled(false);
			btnApprove.setBounds(10, 466, 89, 23);
			btnApprove.addActionListener(this);
		}
		return btnApprove;
	}

	private JLabel GETlblCmnt() {
		if (lblCmnt == null) {
			lblCmnt = new JLabel("Comments:");
			lblCmnt.setBounds(10, 295, 74, 14);
		}
		return lblCmnt;
	}

	private Component GETtxtGrade() {
		if (txtGrade == null) {
			txtGrade = new JTextField();
			txtGrade.setBounds(64, 264, 46, 20);
			txtGrade.setColumns(10);
			txtGrade.setEnabled(false);
			txtGrade.setText("");
			txtGrade.addKeyListener(this);
		}
		return txtGrade;
	}

	private JLabel GETlblExam() {
		if (lblExam == null) {
			lblExam = new JLabel("Exam:");
			lblExam.setBounds(20, 267, 46, 14);
		}
		return lblExam;
	}

	private JButton GETbtnMainMenu() {
		if (btnMainMenu == null) {
			btnMainMenu = new JButton("Main Menu");
			btnMainMenu.setBounds(262, 466, 129, 23);
			btnMainMenu.addActionListener(this);
		}
		return btnMainMenu;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == btnMainMenu) {
			restoreToDefaults();
			lecturerCtrl.handleLectutereGUI(LecturerController.MAIN);
		}
		if (e.getSource() == btnExit) {
			restoreToDefaults();
			lecturerCtrl.handleLectutereGUI(LecturerController.EXIT);
		}
		if (e.getSource() == cboxExmsCodes) {
			if ((examCodesLst != null) || (!examCodesLst.isEmpty())) {
				int comboindex = cboxExmsCodes.getSelectedIndex();
				if ((comboindex < examCodesLst.size()) && (comboindex >= 0)) {
					ExtractedExam selectedExam = examCodesLst.get(comboindex);
					lecturerCtrl.getExamsToApprove(selectedExam);
				}
			}
		}
		if (e.getSource() == btnApprove) {
			int cboxIndex = cboxExmsCodes.getSelectedIndex();
			ComputerizedExam compExm = examsLst
					.get(lstExams.getSelectedIndex());
			if ((Integer.parseInt(txtGrade.getText()) != compExm.getExamGrade())
					&& (txtComnt.getText().equals(""))) {
				Perror.pError("Changing exam's grade requires you to write the reason for this action in the comment section.");
				return;
			}
			compExm.setExamGrade(Integer.parseInt(txtGrade.getText()));
			compExm.setExamComments(txtComnt.getText());
			compExm.setExamApproved(true);
			if (lecturerCtrl.approveGrade(compExm)) {

				examsLst.remove(lstExams.getSelectedIndex());
				model.remove(lstExams.getSelectedIndex());
				if (model.size() == 0) {
					cboxExmsCodes.removeItemAt(cboxIndex);
					examCodesLst.remove(cboxIndex);
				}

			}
			btnApprove.setEnabled(false);
		}

	}
/**
 * restore the JPanel  To Defaults
 */
	public void restoreToDefaults() {
		model.removeAllElements();
		cboxExmsCodes.removeAllItems();
		btnApprove.setEnabled(false);
		txtGrade.setEnabled(false);
		txtComnt.setEnabled(false);
		txtComnt.setText("");
	}
/**
 * 
 * @param compExamsList the Computerized Exam list
 */
	public void addExams(ArrayList<ComputerizedExam> compExamsList) {
		this.examsLst = new ArrayList<ComputerizedExam>();
		this.examsLst.addAll(compExamsList);
		boolean cheatFlag = false;
		model.removeAllElements();
		for (int i = 0; i < (compExamsList.size()); i++) {
			int size = lstExams.getModel().getSize();
			if (examsLst.get(i).getExamSuspectedCopy() == 0)
				model.add(size,
						Integer.toString(examsLst.get(i).getStudentID()));
			else {
				model.add(size,
						"*" + Integer.toString(examsLst.get(i).getStudentID()));
				cheatFlag = true;
			}
		}
		lstExams.addListSelectionListener(this);
		if (cheatFlag)
			lecturerCtrl.cheatAlart();
	}
/**
 * Enabled buttes
 */
	public void valueChanged(ListSelectionEvent e) {
		txtGrade.setEnabled(true);
		txtComnt.setEnabled(true);
		btnApprove.setEnabled(true);
		txtTxmPreview.setText("");
		txtComnt.setText("");

		printExamPreview(lstExams.getSelectedIndex());
	}

	/**
	 *  print the  Exam Preview
	 * @param selectedIndex
	 */
	private void printExamPreview(int selectedIndex) {
		if (selectedIndex >= 0) {
			ComputerizedExam exm = examsLst.get(selectedIndex);
			txtTxmPreview
					.append("Exam: "
							+ exm.getExamCode()
							+ " \texecuted by: "
							+ exm.getStudentID()
							+ "\n"
							+ "Started at: "
							+ new Time(exm.getExamBeginingHour().getTime())
									.toString()
							+ " and Ended at: "
							+ new Time(exm.getExamEndingHour().getTime())
									.toString()
							+ "\n"
							+ "by "
							+ (exm.getExamFinishStatus() == ComputerizedExam.STATUS_STUDENT_FINISHED ? "Student"
									: "Time's up.")
							+ "\n"
							+ (exm.getExamSuspectedCopy() > 0 ? "Automated exams check suspect this exam copied from "
									+ exm.getExamSuspectedCopy() + "'s exam!\n"
									: "\n") + "QUESTIONS:\n");
			for (int i = 0; i < questionsLst.size(); i++) {
				QuestionPerExam attendedQpE = questionsLst.get(i);
				Question attendedQ = questionsLst.get(i).getQuestion();
				txtTxmPreview.append("\n\n#" + (i + 1) + ") ("
						+ attendedQpE.getQuestionGrade() + "):\n"
						+ attendedQ.getqInstructions() + "\n"
						+ attendedQ.getqText() + "\n\nCorrect answer:\n"
						+ attendedQ.getCorrectAns() + "\n\nStudent answer:\n");
				switch (exm.getAnswer(i).getSelectedAnswer()) {
				case 1:
					txtTxmPreview.append(attendedQ.getCorrectAns());
					break;
				case 2:
					txtTxmPreview.append(attendedQ.getAnswerA());
					break;
				case 3:
					txtTxmPreview.append(attendedQ.getAnswerB());
					break;
				case 4:
					txtTxmPreview.append(attendedQ.getAnswerC());
					break;
				}
			}
			txtTxmPreview.select(0, 0);
			txtGrade.setText(Integer.toString(exm.getExamGrade()));
		}
	}

	/**
	 * choose exam and create code  
	 * @param extractedExamsList
	 */
	public void addExamsCodes(ArrayList<ExtractedExam> extractedExamsList) {
		this.examCodesLst = new ArrayList<ExtractedExam>();
		this.examCodesLst.addAll(extractedExamsList);
		for (int i = 0; i < (extractedExamsList.size()); i++)
			cboxExmsCodes.addItem(examCodesLst.get(i).getExamCode() + " : "
					+ examCodesLst.get(i).getSubjectID()
					+ examCodesLst.get(i).getCourseID()
					+ examCodesLst.get(i).getExamID() + " : "
					+ examCodesLst.get(i).getExamExtractDate());
		cboxExmsCodes.addActionListener(this);

	}
/**
 * add question to question list
 * @param questions
 */
	public void addQuestions(ArrayList<QuestionPerExam> questions) {
		this.questionsLst = new ArrayList<QuestionPerExam>();
		this.questionsLst.addAll(questions);

	}

	public void keyReleased(KeyEvent e) {
		if ((e.getSource() == txtGrade) && !(e.getKeyChar() == '\n')) {
			if (!Character.isDigit(e.getKeyChar()))
				txtGrade.setText("");
			if (!txtGrade.getText().isEmpty()) {
				Integer totalPoints = new Integer(Integer.parseInt(txtGrade
						.getText()));
				if (totalPoints > 100) {
					Perror.pError("Total points for the exam will exceed 100!");
					txtGrade.grabFocus();
					btnApprove.setEnabled(false);
				} else
					btnApprove.setEnabled(true);
			} else
				btnApprove.setEnabled(false);
		}
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		

	}

	@Override
	public void keyTyped(KeyEvent arg0) {
	

	}
}
